home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Tools 4
/
Amiga Tools 4.iso
/
grafix
/
raytracing
/
raylab
/
source
/
getworld.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-01-04
|
43KB
|
1,478 lines
/*
name: getworld.c
Input handler
-------------
This part will read and interpret a scene description file.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "defs.h"
#include "getworld.h"
#include "extern.h"
TEXTURE DefaultTexture;
TRANSFORM DefaultTransform;
/*****************************************************************
*
* This is the main imput routine
*
*****************************************************************/
int CreateWorld(char *filename )
{
int RetOK=0,EndReached=-1;
char strtmp[100];
FILE *parfile;
NumObjects=NumLights=0;
SetupDefaults();
if((parfile=fopen(filename,"r"))!=0) {
fprintf(stderr,"\nBuilding scene\n[");
while((EndReached!=0)&&(RetOK==0)&&(getnextkeyword(parfile,strtmp)==0)) {
if(strcmp(strtmp,(char *)"PLANE:")==0)
RetOK=InitNewPlane(parfile);
else if(strcmp(strtmp,(char *)"SPHERE:")==0)
RetOK=InitNewSphere(parfile);
else if(strcmp(strtmp,(char *)"ELLIPSOID:")==0)
RetOK=InitNewEllipsoid(parfile);
else if(strcmp(strtmp,(char *)"TRIANGLE:")==0)
RetOK=InitNewTriangle(parfile);
else if(strcmp(strtmp,(char *)"BOX:")==0)
RetOK=InitNewBox(parfile);
else if(strcmp(strtmp,(char *)"DISC:")==0)
RetOK=InitNewDisc(parfile);
else if(strcmp(strtmp,(char *)"CYLINDER:")==0)
RetOK=InitNewCylinder(parfile);
else if(strcmp(strtmp,(char *)"LIGHT:")==0)
RetOK=InitNewLight(parfile);
else if(strcmp(strtmp,(char *)"CAMERA:")==0)
RetOK=InitCamera(parfile);
else if(strcmp(strtmp,(char *)"GLOBALS:")==0)
RetOK=InitGlobals(parfile);
else if(strcmp(strtmp,(char *)"DEFTEXTURE:")==0)
RetOK=InitTexture(&DefaultTexture,parfile);
else if(strcmp(strtmp,(char *)"DEFTRANSFORM:")==0)
RetOK=InitTransform(&DefaultTransform,parfile);
else if(strcmp(strtmp,(char *)"END")==0) {
EndReached=0;
}
else {
fprintf(stderr,"\n\nError: Unknown keyword \"%s\"",strtmp);
RetOK=-1;
}
}
fprintf(stderr,"]\n\n");
if(NumObjects<=0) {
fprintf(stderr,"No objects were declared!\n");
RetOK=-1;
}
if(NumLights<=0) {
fprintf(stderr,"No lights were declared!\n");
RetOK=-1;
}
if(RetOK!=0) fprintf(stderr,"*** Failed!\n\n");
fclose(parfile);
}
else {
RetOK=-1;
fprintf(stderr,"\n*** Could not open description file!\n");
}
return(RetOK);
}
/*****************************************************************
*
* Initialization routines
*
*****************************************************************/
int InitNewPlane(FILE *parfile)
{
double dtmp;
char strtmp[100];
PLANE TmpPlane, *NewPlane;
OBJECT *NewObject;
TEXTURE TmpText;
TRANSFORM TmpTransform;
int RetOK=0,EndReached=-1;
fprintf(stderr,".");
if(NumObjects>=maxobjects) {
fprintf(stderr,"\n*** Maximum amount of objects exceeded!\n");
RetOK=-1;
}
else {
CopyTexture(&TmpText,&DefaultTexture);
CopyTransform(&TmpTransform,&DefaultTransform);
TmpPlane.Normal.x=0.0; /* Set default values */
TmpPlane.Normal.y=0.0;
TmpPlane.Normal.z=1.0;
TmpPlane.a=0.0;
if(getnextkeyword(parfile,strtmp)==0) { /* Get first keyword */
while((EndReached!=0)&&(RetOK==0)) {
if(strcmp(strtmp,(char *)"NORMAL")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpPlane.Normal.x,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpPlane.Normal.y,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpPlane.Normal.z,dtmp,mincoord,maxcoord,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"OFFSET")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpPlane.a,dtmp,mincoord,maxcoord,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"TEXTURE:")==0) {
RetOK=InitTexture(&TmpText,parfile);
}
else if(strcmp(strtmp,(char *)"TRANSFORM:")==0) {
RetOK=InitTransform(&TmpTransform,parfile);
AddTransform(&TmpText.Transform,&TmpTransform);
}
else if(strcmp(strtmp,(char *)":END")==0) {
EndReached=0;
}
else {
fprintf(stderr,"\nError: Unknown plane-keyword \"%s\"\n",strtmp);
RetOK=-1;
}
if((RetOK==0)&&(EndReached!=0)) {
if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1; /* Get next keyword */
}
}
}
if(RetOK==0) {
if((NewObject=(OBJECT *)malloc(sizeof(OBJECT)))!=NULL) {
if((NewPlane=(PLANE *)malloc(sizeof(PLANE)))!=NULL) {
CopyVector(&NewPlane->Normal,&TmpPlane.Normal);
NewPlane->a=TmpPlane.a;
NewObject->ShapeType=SHAPE_PLANE;
NewObject->Shape=NewPlane;
CopyTexture(&NewObject->Texture,&TmpText);
CopyTransform(&NewObject->Transform,&TmpTransform);
ObjectArray[NumObjects]=NewObject;
NumObjects++;
}
else {
fprintf(stderr,"\nError: Could not allocate memory for new plane\n");
free(NewObject);
RetOK=-1;
}
}
else {
fprintf(stderr,"\nError: Could not allocate memory for new object\n");
RetOK=-1;
}
}
}
return(RetOK);
}
int InitNewSphere(FILE *parfile)
{
double dtmp;
char strtmp[100];
SPHERE TmpSphere, *NewSphere;
OBJECT *NewObject;
TEXTURE TmpText;
TRANSFORM TmpTransform;
int RetOK=0,EndReached=-1;
fprintf(stderr,".");
if(NumObjects>=maxobjects) {
fprintf(stderr,"\n*** Maximum amount of objects exceeded!\n");
RetOK=-1;
}
else {
CopyTexture(&TmpText,&DefaultTexture);
CopyTransform(&TmpTransform,&DefaultTransform);
TmpSphere.Centre.x=0.0; /* Set default values */
TmpSphere.Centre.y=0.0;
TmpSphere.Centre.z=0.0;
TmpSphere.r=1.0;
if(getnextkeyword(parfile,strtmp)==0) { /* Get first keyword */
while((EndReached!=0)&&(RetOK==0)) {
if(strcmp(strtmp,(char *)"CENTRE")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpSphere.Centre.x,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpSphere.Centre.y,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpSphere.Centre.z,dtmp,mincoord,maxcoord,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"RADIUS")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpSphere.r,dtmp,mincoord,maxcoord,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"TEXTURE:")==0) {
RetOK=InitTexture(&TmpText,parfile);
}
else if(strcmp(strtmp,(char *)"TRANSFORM:")==0) {
RetOK=InitTransform(&TmpTransform,parfile);
AddTransform(&TmpText.Transform,&TmpTransform);
}
else if(strcmp(strtmp,(char *)":END")==0) {
EndReached=0;
}
else {
fprintf(stderr,"\nError: Unknown sphere-keyword \"%s\"\n",strtmp);
RetOK=-1;
}
if((RetOK==0)&&(EndReached!=0)) {
if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1; /* Get next keyword */
}
}
}
if(RetOK==0) {
if((NewObject=(OBJECT *)malloc(sizeof(OBJECT)))!=NULL) {
if((NewSphere=(SPHERE *)malloc(sizeof(SPHERE)))!=NULL) {
CopyPoint(&NewSphere->Centre,&TmpSphere.Centre);
NewSphere->r=TmpSphere.r;
NewObject->ShapeType=SHAPE_SPHERE;
NewObject->Shape=NewSphere;
CopyTexture(&NewObject->Texture,&TmpText);
CopyTransform(&NewObject->Transform,&TmpTransform);
ObjectArray[NumObjects]=NewObject;
NumObjects++;
}
else {
fprintf(stderr,"\nError: Could not allocate memory for new sphere\n");
free(NewObject);
RetOK=-1;
}
}
else {
fprintf(stderr,"\nError: Could not allocate memory for new object\n");
RetOK=-1;
}
}
}
return(RetOK);
}
int InitNewEllipsoid(FILE *parfile)
{
double dtmp;
char strtmp[100];
ELLIPSOID TmpEllipsoid, *NewEllipsoid;
OBJECT *NewObject;
TEXTURE TmpText;
TRANSFORM TmpTransform;
int RetOK=0,EndReached=-1;
fprintf(stderr,".");
if(NumObjects>=maxobjects) {
fprintf(stderr,"\n*** Maximum amount of objects exceeded!\n");
RetOK=-1;
}
else {
CopyTexture(&TmpText,&DefaultTexture);
CopyTransform(&TmpTransform,&DefaultTransform);
TmpEllipsoid.Centre.x=0.0; /* Set default values */
TmpEllipsoid.Centre.y=0.0;
TmpEllipsoid.Centre.z=0.0;
TmpEllipsoid.Radius.x=1.0;
TmpEllipsoid.Radius.y=1.0;
TmpEllipsoid.Radius.z=1.0;
if(getnextkeyword(parfile,strtmp)==0) { /* Get first keyword */
while((EndReached!=0)&&(RetOK==0)) {
if(strcmp(strtmp,(char *)"CENTRE")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpEllipsoid.Centre.x,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpEllipsoid.Centre.y,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpEllipsoid.Centre.z,dtmp,mincoord,maxcoord,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"RADIUS")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpEllipsoid.Radius.x,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpEllipsoid.Radius.y,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpEllipsoid.Radius.z,dtmp,mincoord,maxcoord,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"TEXTURE:")==0) {
RetOK=InitTexture(&TmpText,parfile);
}
else if(strcmp(strtmp,(char *)"TRANSFORM:")==0) {
RetOK=InitTransform(&TmpTransform,parfile);
AddTransform(&TmpText.Transform,&TmpTransform);
}
else if(strcmp(strtmp,(char *)":END")==0) {
EndReached=0;
}
else {
fprintf(stderr,"\nError: Unknown ellipsoid-keyword \"%s\"\n",strtmp);
RetOK=-1;
}
if((RetOK==0)&&(EndReached!=0)) {
if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1; /* Get next keyword */
}
}
}
if(RetOK==0) {
if((NewObject=(OBJECT *)malloc(sizeof(OBJECT)))!=NULL) {
if((NewEllipsoid=(ELLIPSOID *)malloc(sizeof(ELLIPSOID)))!=NULL) {
CopyPoint(&NewEllipsoid->Centre,&TmpEllipsoid.Centre);
CopyVector(&NewEllipsoid->Radius,&TmpEllipsoid.Radius);
NewObject->ShapeType=SHAPE_ELLIPSOID;
NewObject->Shape=NewEllipsoid;
CopyTexture(&NewObject->Texture,&TmpText);
CopyTransform(&NewObject->Transform,&TmpTransform);
ObjectArray[NumObjects]=NewObject;
NumObjects++;
}
else {
fprintf(stderr,"\nError: Could not allocate memory for new ellipsoid\n");
free(NewObject);
RetOK=-1;
}
}
else {
fprintf(stderr,"\nError: Could not allocate memory for new object\n");
RetOK=-1;
}
}
}
return(RetOK);
}
int InitNewTriangle(FILE *parfile)
{
double dtmp,maxx,maxy,maxz,minx,miny,minz;
char strtmp[100];
TRIANGLE *NewTriangle;
TRANSFORM TmpTransform;
POINT Corners[3];
OBJECT *NewObject;
TEXTURE TmpText;
VECTOR v1,v2,n;
int RetOK=0,EndReached=-1,i;
fprintf(stderr,".");
if(NumObjects>=maxobjects) {
fprintf(stderr,"\n*** Maximum amount of objects exceeded!\n");
RetOK=-1;
}
else {
CopyTexture(&TmpText,&DefaultTexture);
CopyTransform(&TmpTransform,&DefaultTransform);
Corners[0].x=0.0; /* Set default values */
Corners[0].y=0.0;
Corners[0].z=0.0;
Corners[1].x=1.0;
Corners[1].y=1.0;
Corners[1].z=1.0;
Corners[2].x=-1.0;
Corners[2].y=1.0;
Corners[2].z=1.0;
if(getnextkeyword(parfile,strtmp)==0) { /* Get first keyword */
while((EndReached!=0)&&(RetOK==0)) {
if(strcmp(strtmp,(char *)"CORNERS")==0) {
i=0;
while((i<3)&&(EndReached!=0)) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&Corners[i].x,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&Corners[i].y,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&Corners[i].z,dtmp,mincoord,maxcoord,strtmp);
else EndReached=0;
i++;
}
}
else if(strcmp(strtmp,(char *)"TEXTURE:")==0) {
RetOK=InitTexture(&TmpText,parfile);
}
else if(strcmp(strtmp,(char *)"TRANSFORM:")==0) {
RetOK=InitTransform(&TmpTransform,parfile);
AddTransform(&TmpText.Transform,&TmpTransform);
}
else if(strcmp(strtmp,(char *)":END")==0) {
EndReached=0;
}
else {
fprintf(stderr,"\nError: Unknown triangle-keyword \"%s\"\n",strtmp);
RetOK=-1;
}
if((RetOK==0)&&(EndReached!=0)) {
if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1; /* Get next keyword */
}
}
}
if(RetOK==0) {
if((NewObject=(OBJECT *)malloc(sizeof(OBJECT)))!=NULL) {
if((NewTriangle=(TRIANGLE *)malloc(sizeof(TRIANGLE)))!=NULL) {
for(i=0;i<3;i++) {
CopyPoint(&NewTriangle->Corners[i],&Corners[i]);
}
v1.x=Corners[1].x-Corners[0].x;
v1.y=Corners[1].y-Corners[0].y;
v1.z=Corners[1].z-Corners[0].z;
v2.x=Corners[2].x-Corners[0].x;
v2.y=Corners[2].y-Corners[0].y;
v2.z=Corners[2].z-Corners[0].z;
CrossProduct(&n,&v1,&v2);
CopyVector(&NewTriangle->Plane.Normal,&n);
NewTriangle->Plane.a=Corners[0].x*n.x+Corners[0].y*n.y+Corners[0].z*n.z;
minx=maxx=Corners[0].x; /* Calculate min/max boundaries for x,y,z... */
miny=maxy=Corners[0].y; /* This significantly speeds up the checking */
minz=maxz=Corners[0].z; /* for ray-intersections. */
if(Corners[1].x>maxx) maxx=Corners[1].x;
else if(Corners[1].x<minx) minx=Corners[1].x;
if(Corners[2].x>maxx) maxx=Corners[2].x;
else if(Corners[2].x<minx) minx=Corners[2].x;
if(Corners[1].y>maxy) maxy=Corners[1].y;
else if(Corners[1].y<miny) miny=Corners[1].y;
if(Corners[2].y>maxy) maxy=Corners[2].y;
else if(Corners[2].y<miny) miny=Corners[2].y;
if(Corners[1].z>maxz) maxz=Corners[1].z;
else if(Corners[1].z<minz) minz=Corners[1].z;
if(Corners[2].z>maxz) maxz=Corners[2].z;
else if(Corners[2].z<minz) minz=Corners[2].z;
NewTriangle->Min.x=minx; NewTriangle->Max.x=maxx;
NewTriangle->Min.y=miny; NewTriangle->Max.y=maxy;
NewTriangle->Min.z=minz; NewTriangle->Max.z=maxz;
NewObject->ShapeType=SHAPE_TRIANGLE;
NewObject->Shape=NewTriangle;
CopyTexture(&NewObject->Texture,&TmpText);
CopyTransform(&NewObject->Transform,&TmpTransform);
ObjectArray[NumObjects]=NewObject;
NumObjects++;
}
else {
fprintf(stderr,"\nError: Could not allocate memory for new triangle\n");
free(NewObject);
RetOK=-1;
}
}
else {
fprintf(stderr,"\nError: Could not allocate memory for new object\n");
RetOK=-1;
}
}
}
return(RetOK);
}
int InitNewBox(FILE *parfile)
{
double dtmp,maxx,maxy,maxz,minx,miny,minz;
char strtmp[100];
BOX *NewBox;
POINT Corners[2];
OBJECT *NewObject;
TEXTURE TmpText;
TRANSFORM TmpTransform;
int RetOK=0,EndReached=-1,i;
fprintf(stderr,".");
if(NumObjects>=maxobjects) {
fprintf(stderr,"\n*** Maximum amount of objects exceeded!\n");
RetOK=-1;
}
else {
CopyTexture(&TmpText,&DefaultTexture);
CopyTransform(&TmpTransform,&DefaultTransform);
Corners[0].x=0.0; /* Set default values */
Corners[0].y=0.0;
Corners[0].z=0.0;
Corners[1].x=1.0;
Corners[1].y=1.0;
Corners[1].z=1.0;
if(getnextkeyword(parfile,strtmp)==0) { /* Get first keyword */
while((EndReached!=0)&&(RetOK==0)) {
if(strcmp(strtmp,(char *)"CORNERS")==0) {
i=0;
while((i<2)&&(EndReached!=0)) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&Corners[i].x,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&Corners[i].y,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&Corners[i].z,dtmp,mincoord,maxcoord,strtmp);
else EndReached=0;
i++;
}
}
else if(strcmp(strtmp,(char *)"TEXTURE:")==0) {
RetOK=InitTexture(&TmpText,parfile);
}
else if(strcmp(strtmp,(char *)"TRANSFORM:")==0) {
RetOK=InitTransform(&TmpTransform,parfile);
AddTransform(&TmpText.Transform,&TmpTransform);
}
else if(strcmp(strtmp,(char *)":END")==0) {
EndReached=0;
}
else {
fprintf(stderr,"\nError: Unknown box-keyword \"%s\"\n",strtmp);
RetOK=-1;
}
if((RetOK==0)&&(EndReached!=0)) {
if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1; /* Get next keyword */
}
}
}
if(RetOK==0) {
if((NewObject=(OBJECT *)malloc(sizeof(OBJECT)))!=NULL) {
if((NewBox=(BOX *)malloc(sizeof(BOX)))!=NULL) {
CreateVector(&NewBox->Planes[0].Normal,-1.0,0.0,0.0);
CreateVector(&NewBox->Planes[1].Normal,1.0,0.0,0.0);
CreateVector(&NewBox->Planes[2].Normal,0.0,-1.0,0.0);
CreateVector(&NewBox->Planes[3].Normal,0.0,1.0,0.0);
CreateVector(&NewBox->Planes[4].Normal,0.0,0.0,-1.0);
CreateVector(&NewBox->Planes[5].Normal,0.0,0.0,1.0);
minx=maxx=Corners[0].x; /* Calculate min/max boundaries for x,y,z... */
miny=maxy=Corners[0].y; /* This is so that you can give the coordinates */
minz=maxz=Corners[0].z; /* in any order. */
if(Corners[1].x>maxx) maxx=Corners[1].x;
else if(Corners[1].x<minx) minx=Corners[1].x;
if(Corners[1].y>maxy) maxy=Corners[1].y;
else if(Corners[1].y<miny) miny=Corners[1].y;
if(Corners[1].z>maxz) maxz=Corners[1].z;
else if(Corners[1].z<minz) minz=Corners[1].z;
NewBox->Planes[0].a=-minx;
NewBox->Planes[1].a=maxx;
NewBox->Planes[2].a=-miny;
NewBox->Planes[3].a=maxy;
NewBox->Planes[4].a=-minz;
NewBox->Planes[5].a=maxz;
CreatePoint(&NewBox->Corners[0],minx,miny,minz);
CreatePoint(&NewBox->Corners[1],maxx,maxy,maxz);
NewObject->ShapeType=SHAPE_BOX;
NewObject->Shape=NewBox;
CopyTexture(&NewObject->Texture,&TmpText);
CopyTransform(&NewObject->Transform,&TmpTransform);
ObjectArray[NumObjects]=NewObject;
NumObjects++;
}
else {
fprintf(stderr,"\nError: Could not allocate memory for new box\n");
free(NewObject);
RetOK=-1;
}
}
else {
fprintf(stderr,"\nError: Could not allocate memory for new object\n");
RetOK=-1;
}
}
}
return(RetOK);
}
int InitNewDisc(FILE *parfile)
{
double dtmp;
char strtmp[100];
DISC TmpDisc, *NewDisc;
OBJECT *NewObject;
TEXTURE TmpText;
TRANSFORM TmpTransform;
int RetOK=0,EndReached=-1;
fprintf(stderr,".");
if(NumObjects>=maxobjects) {
fprintf(stderr,"\n*** Maximum amount of objects exceeded!\n");
RetOK=-1;
}
else {
CopyTexture(&TmpText,&DefaultTexture);
CopyTransform(&TmpTransform,&DefaultTransform);
TmpDisc.Plane.Normal.x=0.0; /* Set default values */
TmpDisc.Plane.Normal.y=0.0;
TmpDisc.Plane.Normal.z=1.0;
TmpDisc.Plane.a=0.0;
TmpDisc.r=1.0;
if(getnextkeyword(parfile,strtmp)==0) { /* Get first keyword */
while((EndReached!=0)&&(RetOK==0)) {
if(strcmp(strtmp,(char *)"NORMAL")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpDisc.Plane.Normal.x,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpDisc.Plane.Normal.y,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpDisc.Plane.Normal.z,dtmp,mincoord,maxcoord,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"CENTRE")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpDisc.Centre.x,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpDisc.Centre.y,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpDisc.Centre.z,dtmp,mincoord,maxcoord,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"RADIUS")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpDisc.r,dtmp,mincoord,maxcoord,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"TEXTURE:")==0) {
RetOK=InitTexture(&TmpText,parfile);
}
else if(strcmp(strtmp,(char *)"TRANSFORM:")==0) {
RetOK=InitTransform(&TmpTransform,parfile);
AddTransform(&TmpText.Transform,&TmpTransform);
}
else if(strcmp(strtmp,(char *)":END")==0) {
EndReached=0;
}
else {
fprintf(stderr,"\nError: Unknown disc-keyword \"%s\"\n",strtmp);
RetOK=-1;
}
if((RetOK==0)&&(EndReached!=0)) {
if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1; /* Get next keyword */
}
}
}
if(RetOK==0) {
if((NewObject=(OBJECT *)malloc(sizeof(OBJECT)))!=NULL) {
if((NewDisc=(DISC *)malloc(sizeof(DISC)))!=NULL) {
CopyPoint(&NewDisc->Centre,&TmpDisc.Centre);
NewDisc->r=TmpDisc.r;
CopyVector(&NewDisc->Plane.Normal,&TmpDisc.Plane.Normal);
NewDisc->Plane.a=(TmpDisc.Plane.Normal.x*TmpDisc.Centre.x+TmpDisc.Plane.Normal.y*TmpDisc.Centre.y+TmpDisc.Plane.Normal.z*TmpDisc.Centre.z);
NewObject->ShapeType=SHAPE_DISC;
NewObject->Shape=NewDisc;
CopyTexture(&NewObject->Texture,&TmpText);
CopyTransform(&NewObject->Transform,&TmpTransform);
ObjectArray[NumObjects]=NewObject;
NumObjects++;
}
else {
fprintf(stderr,"\nError: Could not allocate memory for new disc\n");
free(NewObject);
RetOK=-1;
}
}
else {
fprintf(stderr,"\nError: Could not allocate memory for new object\n");
RetOK=-1;
}
}
}
return(RetOK);
}
int InitNewCylinder(FILE *parfile)
{
double dtmp,nx,ny,nz;
char strtmp[100];
CYLINDER TmpCyl, *NewCyl;
OBJECT *NewObject;
TEXTURE TmpText;
TRANSFORM TmpTransform;
int RetOK=0,EndReached=-1;
fprintf(stderr,".");
if(NumObjects>=maxobjects) {
fprintf(stderr,"\n*** Maximum amount of objects exceeded!\n");
RetOK=-1;
}
else {
CopyTexture(&TmpText,&DefaultTexture);
CopyTransform(&TmpTransform,&DefaultTransform);
CreatePoint(&TmpCyl.Ends[0],0.0,0.0,0.0);
CreatePoint(&TmpCyl.Ends[1],0.0,0.0,1.0);
TmpCyl.r=1.0;
if(getnextkeyword(parfile,strtmp)==0) { /* Get first keyword */
while((EndReached!=0)&&(RetOK==0)) {
if(strcmp(strtmp,(char *)"HEIGHT")==0) {
if(getnextnumber(parfile,&dtmp)==0) {
set_dvalue(&TmpCyl.Ends[1].z,dtmp,mincoord,maxcoord,strtmp);
TmpCyl.Ends[0].x=TmpCyl.Ends[0].y=TmpCyl.Ends[0].z=TmpCyl.Ends[1].x=TmpCyl.Ends[1].y=0.0;
}
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"START")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpCyl.Ends[0].x,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpCyl.Ends[0].y,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpCyl.Ends[0].z,dtmp,mincoord,maxcoord,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"END")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpCyl.Ends[1].x,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpCyl.Ends[1].y,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpCyl.Ends[1].z,dtmp,mincoord,maxcoord,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"RADIUS")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpCyl.r,dtmp,mincoord,maxcoord,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"TEXTURE:")==0) {
RetOK=InitTexture(&TmpText,parfile);
}
else if(strcmp(strtmp,(char *)"TRANSFORM:")==0) {
RetOK=InitTransform(&TmpTransform,parfile);
AddTransform(&TmpText.Transform,&TmpTransform);
}
else if(strcmp(strtmp,(char *)":END")==0) {
EndReached=0;
}
else {
fprintf(stderr,"\nError: Unknown cylinder-keyword \"%s\"\n",strtmp);
RetOK=-1;
}
if((RetOK==0)&&(EndReached!=0)) {
if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1; /* Get next keyword */
}
}
}
if(RetOK==0) {
if((NewObject=(OBJECT *)malloc(sizeof(OBJECT)))!=NULL) {
if((NewCyl=(CYLINDER *)malloc(sizeof(CYLINDER)))!=NULL) {
CopyPoint(&NewCyl->Ends[0],&TmpCyl.Ends[0]);
CopyPoint(&NewCyl->Ends[1],&TmpCyl.Ends[1]);
CopyPoint(&NewCyl->Discs[1].Centre,&TmpCyl.Ends[1]);
CopyPoint(&NewCyl->Discs[0].Centre,&TmpCyl.Ends[0]);
NewCyl->Discs[0].r=TmpCyl.r;
NewCyl->Discs[1].r=TmpCyl.r;
CreateVector(&NewCyl->Discs[1].Plane.Normal,TmpCyl.Ends[1].x-TmpCyl.Ends[0].x,TmpCyl.Ends[1].y-TmpCyl.Ends[0].y,TmpCyl.Ends[1].z-TmpCyl.Ends[0].z);
NegVector(&NewCyl->Discs[0].Plane.Normal,&NewCyl->Discs[1].Plane.Normal);
nx=NewCyl->Discs[0].Plane.Normal.x*NewCyl->Discs[0].Centre.x;
ny=NewCyl->Discs[0].Plane.Normal.y*NewCyl->Discs[0].Centre.y;
nz=NewCyl->Discs[0].Plane.Normal.z*NewCyl->Discs[0].Centre.z;
NewCyl->Discs[0].Plane.a=nx+ny+nz;
nx=NewCyl->Discs[1].Plane.Normal.x*NewCyl->Discs[1].Centre.x;
ny=NewCyl->Discs[1].Plane.Normal.y*NewCyl->Discs[1].Centre.y;
nz=NewCyl->Discs[1].Plane.Normal.z*NewCyl->Discs[1].Centre.z;
NewCyl->Discs[1].Plane.a=nx+ny+nz;
NewCyl->r=TmpCyl.r;
NewObject->ShapeType=SHAPE_CYLINDER;
NewObject->Shape=NewCyl;
CopyTexture(&NewObject->Texture,&TmpText);
CopyTransform(&NewObject->Transform,&TmpTransform);
ObjectArray[NumObjects]=NewObject;
NumObjects++;
}
else {
fprintf(stderr,"\nError: Could not allocate memory for new cylinder\n");
free(NewObject);
RetOK=-1;
}
}
else {
fprintf(stderr,"\nError: Could not allocate memory for new object\n");
RetOK=-1;
}
}
}
return(RetOK);
}
int InitNewLight(FILE *parfile)
{
double dtmp;
char strtmp[100];
LIGHT TmpLight, *NewLight;
int RetOK=0,EndReached=-1;
fprintf(stderr,".");
if(NumLights>=maxlights) {
fprintf(stderr,"\n*** Maximum amount of lights exceeded!\n");
RetOK=-1;
}
else {
TmpLight.Location.x=10.0; /* Set default values */
TmpLight.Location.y=-10.0;
TmpLight.Location.z=10.0;
TmpLight.Color.r=TmpLight.Color.g=TmpLight.Color.b=1.0;
if(getnextkeyword(parfile,strtmp)==0) { /* Get first keyword */
while((EndReached!=0)&&(RetOK==0)) {
if(strcmp(strtmp,(char *)"LOCATION")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpLight.Location.x,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpLight.Location.y,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpLight.Location.z,dtmp,mincoord,maxcoord,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"COLOR")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpLight.Color.r,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpLight.Color.g,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpLight.Color.b,dtmp,mincoord,maxcoord,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)":END")==0) {
EndReached=0;
}
else {
fprintf(stderr,"\nError: Unknown light-keyword \"%s\"\n",strtmp);
RetOK=-1;
}
if((RetOK==0)&&(EndReached!=0)) {
if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1; /* Get next keyword */
}
}
}
if(RetOK==0) {
if((NewLight=(LIGHT *)malloc(sizeof(LIGHT)))!=NULL) {
CopyPoint(&NewLight->Location,&TmpLight.Location);
NewLight->Color.r=TmpLight.Color.r;
NewLight->Color.g=TmpLight.Color.g;
NewLight->Color.b=TmpLight.Color.b;
LightArray[NumLights]=NewLight;
NumLights++;
}
else {
fprintf(stderr,"\nError: Could not allocate memory for new light\n");
RetOK=-1;
}
}
}
return(RetOK);
}
int InitCamera(FILE *parfile)
{
double dtmp;
char strtmp[100];
int RetOK=0,EndReached=-1;
fprintf(stderr,".");
if(getnextkeyword(parfile,strtmp)==0) { /* Get first keyword */
while((EndReached!=0)&&(RetOK==0)) {
if(strcmp(strtmp,(char *)"LOCATION")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&Camera.Location.x,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&Camera.Location.y,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&Camera.Location.z,dtmp,mincoord,maxcoord,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"VIEWPOINT")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&Camera.ViewPoint.x,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&Camera.ViewPoint.y,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&Camera.ViewPoint.z,dtmp,mincoord,maxcoord,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"ASPECT")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&Camera.Aspect.x,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&Camera.Aspect.y,dtmp,mincoord,maxcoord,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&Camera.Aspect.z,dtmp,mincoord,maxcoord,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)":END")==0) {
EndReached=0;
}
else {
fprintf(stderr,"\nError: Unknown camera-keyword \"%s\"\n",strtmp);
RetOK=-1;
}
if((RetOK==0)&&(EndReached!=0)) {
if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1; /* Get next keyword */
}
}
}
if(RetOK==0)
CreateCamera(&Camera, &Camera.Location, &Camera.ViewPoint, &Camera.Aspect);
return(RetOK);
}
int InitTexture(TEXTURE *TmpTexture, FILE *parfile)
{
double dtmp,d2tmp;
char strtmp[100],strtmp2[100];
int RetOK=0,EndReached=-1;
long lastbound,i;
/* fprintf(stderr,"."); */
/* CopyTransform(&TmpTexture->Transform,&DefaultTransform); */
if(getnextkeyword(parfile,strtmp)==0) { /* Get first keyword */
while((EndReached!=0)&&(RetOK==0)) {
if(strcmp(strtmp,(char *)"COLOR")==0) {
if(getnextnumber(parfile,&dtmp)==0) {
set_dvalue(&d2tmp,dtmp,0.0,1.0,strtmp);
TmpTexture->CMap.Colors[0].r=d2tmp;
}
if(getnextnumber(parfile,&dtmp)==0) {
set_dvalue(&d2tmp,dtmp,0.0,1.0,strtmp);
TmpTexture->CMap.Colors[0].g=d2tmp;
}
if(getnextnumber(parfile,&dtmp)==0) {
set_dvalue(&d2tmp,dtmp,0.0,1.0,strtmp);
TmpTexture->CMap.Colors[0].b=d2tmp;
}
else EndReached=0L;
TmpTexture->CMap.Colors[1].r=TmpTexture->CMap.Colors[1].g=TmpTexture->CMap.Colors[1].b=0.0;
TmpTexture->CMap.Bounds[0]=0.0;
TmpTexture->CMap.Bounds[1]=1.0;
TmpTexture->CMap.LastBound=1;
}
else if(strcmp(strtmp,(char *)"COLORMAP")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_ivalue(&lastbound,(long)floor(dtmp),1,10,strtmp);
lastbound--;
i=0;
while((i<=lastbound)&&(EndReached!=0)) {
if(getnextnumber(parfile,&dtmp)==0) {
set_dvalue(&d2tmp,dtmp,0.0,1.0,strtmp);
TmpTexture->CMap.Bounds[i]=d2tmp;
}
if(getnextnumber(parfile,&dtmp)==0) {
set_dvalue(&d2tmp,dtmp,0.0,1.0,strtmp);
TmpTexture->CMap.Colors[i].r=d2tmp;
}
if(getnextnumber(parfile,&dtmp)==0) {
set_dvalue(&d2tmp,dtmp,0.0,1.0,strtmp);
TmpTexture->CMap.Colors[i].g=d2tmp;
}
if(getnextnumber(parfile,&dtmp)==0) {
set_dvalue(&d2tmp,dtmp,0.0,1.0,strtmp);
TmpTexture->CMap.Colors[i].b=d2tmp;
i++;
}
else EndReached=0L;
}
TmpTexture->CMap.LastBound=i;
}
else if(strcmp(strtmp,(char *)"PATTERN")==0) {
if(getnextkeyword(parfile,strtmp2)==0) {
if(strcmp(strtmp2,(char *)"NONE")==0)
TmpTexture->Pattern=PATTERN_NONE;
else if(strcmp(strtmp2,(char *)"CHECKER")==0)
TmpTexture->Pattern=PATTERN_CHECKER;
else if(strcmp(strtmp2,(char *)"CIRCLES")==0)
TmpTexture->Pattern=PATTERN_CIRCLES;
else if(strcmp(strtmp2,(char *)"RINGS")==0)
TmpTexture->Pattern=PATTERN_RINGS;
else if(strcmp(strtmp2,(char *)"SPOTS")==0)
TmpTexture->Pattern=PATTERN_SPOTS;
else if(strcmp(strtmp2,(char *)"GRADIENT")==0)
TmpTexture->Pattern=PATTERN_GRADIENT;
else {
fprintf(stderr,"\nError: Unknown pattern identifier \"%s\"\n",strtmp2);
RetOK=-1;
}
}
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"REFLECT")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpTexture->Reflect.r,dtmp,0.0,1.0,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpTexture->Reflect.g,dtmp,0.0,1.0,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpTexture->Reflect.b,dtmp,0.0,1.0,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"FILTER")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpTexture->Filter.r,dtmp,0.0,1.0,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpTexture->Filter.g,dtmp,0.0,1.0,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpTexture->Filter.b,dtmp,0.0,1.0,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"IOR")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpTexture->Ior,dtmp,1.0,2.0,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"AMBIENT")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpTexture->Ambient,dtmp,0.0,1.0,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"DIFFUSE")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpTexture->Diffuse,dtmp,0.0,1.0,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"PHONG")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpTexture->Phong,dtmp,0.0,1.0,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"PHONGSIZE")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&TmpTexture->PhongSize,dtmp,0.0,100.0,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"TRANSFORM:")==0) {
InitTransform(&TmpTexture->Transform,parfile);
}
else if(strcmp(strtmp,(char *)"DEFAULT")==0) {
CreateDefTexture(TmpTexture);
}
else if(strcmp(strtmp,(char *)":END")==0) {
EndReached=0;
}
else {
fprintf(stderr,"\nError: Unknown texture-keyword \"%s\"\n",strtmp);
RetOK=-1;
}
if((RetOK==0)&&(EndReached!=0)) {
if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1; /* Get next keyword */
}
}
}
return(RetOK);
}
int InitTransform(TRANSFORM *TmpTransform, FILE *parfile)
{
double dtmp,d2tmp;
char strtmp[100];
int RetOK=0,EndReached=-1;
long numtransforms;
/* fprintf(stderr,"."); */
numtransforms=TmpTransform->NumTransforms;
if(getnextkeyword(parfile,strtmp)==0) { /* Get first keyword */
while((EndReached!=0)&&(RetOK==0)) {
if(numtransforms>=10) {
fprintf(stderr,"\n*** Maximum amount of transforms exceeded\n");
RetOK=-1;
}
else if(strcmp(strtmp,(char *)"SCALE")==0) {
TmpTransform->Entry[numtransforms].Type=TRANSFORM_SCALE;
if(getnextnumber(parfile,&dtmp)==0) {
set_dvalue(&d2tmp,dtmp,EPSILON,maxcoord,strtmp);
TmpTransform->Entry[numtransforms].Values.x=d2tmp;
}
if(getnextnumber(parfile,&dtmp)==0) {
set_dvalue(&d2tmp,dtmp,EPSILON,maxcoord,strtmp);
TmpTransform->Entry[numtransforms].Values.y=d2tmp;
}
if(getnextnumber(parfile,&dtmp)==0) {
set_dvalue(&d2tmp,dtmp,EPSILON,maxcoord,strtmp);
TmpTransform->Entry[numtransforms].Values.z=d2tmp;
}
else EndReached=0L;
if((TmpTransform->Entry[numtransforms].Values.x!=1.0)||(TmpTransform->Entry[numtransforms].Values.y!=1.0)||(TmpTransform->Entry[numtransforms].Values.z!=1.0))
numtransforms++;
}
else if(strcmp(strtmp,(char *)"MOVE")==0) {
TmpTransform->Entry[numtransforms].Type=TRANSFORM_MOVE;
if(getnextnumber(parfile,&dtmp)==0) {
set_dvalue(&d2tmp,dtmp,mincoord,maxcoord,strtmp);
TmpTransform->Entry[numtransforms].Values.x=d2tmp;
}
if(getnextnumber(parfile,&dtmp)==0) {
set_dvalue(&d2tmp,dtmp,mincoord,maxcoord,strtmp);
TmpTransform->Entry[numtransforms].Values.y=d2tmp;
}
if(getnextnumber(parfile,&dtmp)==0) {
set_dvalue(&d2tmp,dtmp,mincoord,maxcoord,strtmp);
TmpTransform->Entry[numtransforms].Values.z=d2tmp;
}
else EndReached=0L;
if((TmpTransform->Entry[numtransforms].Values.x!=0.0)||(TmpTransform->Entry[numtransforms].Values.y!=0.0)||(TmpTransform->Entry[numtransforms].Values.z!=0.0))
numtransforms++;
}
else if(strcmp(strtmp,(char *)"ROTATE")==0) {
TmpTransform->Entry[numtransforms].Type=TRANSFORM_ROTATE;
if(getnextnumber(parfile,&dtmp)==0) {
set_dvalue(&d2tmp,dtmp,-99999.0,99999.0,strtmp);
dtmp=fmod(d2tmp,360.0)*RADPDEG; /* Transform from degrees to radians */
TmpTransform->Entry[numtransforms].Values.x=dtmp;
}
if(getnextnumber(parfile,&dtmp)==0) {
set_dvalue(&d2tmp,dtmp,-99999.0,99999.0,strtmp);
dtmp=fmod(d2tmp,360.0)*RADPDEG;
TmpTransform->Entry[numtransforms].Values.y=dtmp;
}
if(getnextnumber(parfile,&dtmp)==0) {
set_dvalue(&d2tmp,dtmp,-99999.0,99999.0,strtmp);
dtmp=fmod(d2tmp,360.0)*RADPDEG;
TmpTransform->Entry[numtransforms].Values.z=dtmp;
}
else EndReached=0L;
if((TmpTransform->Entry[numtransforms].Values.x!=0.0)||(TmpTransform->Entry[numtransforms].Values.y!=0.0)||(TmpTransform->Entry[numtransforms].Values.z!=0.0))
numtransforms++;
}
else if(strcmp(strtmp,(char *)"NONE")==0) {
ClearTransform(TmpTransform);
}
else if(strcmp(strtmp,(char *)":END")==0) {
EndReached=0;
}
else {
fprintf(stderr,"\nError: Unknown transform-keyword \"%s\"\n",strtmp);
RetOK=-1;
}
if((RetOK==0)&&(EndReached!=0)) {
if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1; /* Get next keyword */
}
}
if((RetOK==0)&&(EndReached==0)) {
TmpTransform->NumTransforms=numtransforms;
}
}
return(RetOK);
}
int InitGlobals(FILE *parfile)
{
double dtmp;
char strtmp[100];
int RetOK=0,EndReached=-1;
fprintf(stderr,".");
if(getnextkeyword(parfile,strtmp)==0) { /* Get first keyword */
while((EndReached!=0)&&(RetOK==0)) {
if(strcmp(strtmp,(char *)"BACKGROUNDCOLOR")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&BackgroundColor.r,dtmp,0.0,1.0,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&BackgroundColor.g,dtmp,0.0,1.0,strtmp);
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&BackgroundColor.b,dtmp,0.0,1.0,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"RECDEPTH")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_ivalue(&RecDepth,(long)floor(dtmp),1,50,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"PICWIDTH")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_ivalue(&PicWidth,(long)floor(dtmp),1,5000,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"PICHEIGHT")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_ivalue(&PicHeight,(long)floor(dtmp),1,5000,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"ANTIALIASREC")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_ivalue(&AntiAliasingRec,(long)floor(dtmp),0,3,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"ANTIALIASTHRESHOLD")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_dvalue(&AntiAliasingThreshold,dtmp,0.0,3.0,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)"DISPLAY")==0) {
if(getnextnumber(parfile,&dtmp)==0)
set_ivalue(&ReqDisplayType,(long)floor(dtmp),0,9999,strtmp);
else EndReached=0;
}
else if(strcmp(strtmp,(char *)":END")==0) {
EndReached=0;
}
else {
fprintf(stderr,"\nError: Unknown globals keyword \"%s\"\n",strtmp);
RetOK=-1;
}
if((RetOK==0)&&(EndReached!=0)) {
if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1; /* Get next keyword */
}
}
}
return(RetOK);
}
/*****************************************************************
*
* Setup default globals
*
*****************************************************************/
void SetupDefaults(void)
{
RecDepth=3;
PicWidth=200; PicHeight=150;
BackgroundColor.r=0.0; BackgroundColor.g=0.0; BackgroundColor.b=0.0;
AntiAliasingRec=0L; AntiAliasingThreshold=0.3; AntiAliasingJitter=0.05;
ReqDisplayType=0L;
Camera.Location.x=0.0; Camera.Location.y=-10.0; Camera.Location.z=1.0;
Camera.ViewPoint.x=0.0; Camera.ViewPoint.y=0.0; Camera.ViewPoint.z=0.0;
Camera.Aspect.x=4.0; Camera.Aspect.y=3.0; Camera.Aspect.z=5.0;
CreateCamera(&Camera, &Camera.Location, &Camera.ViewPoint, &Camera.Aspect);
CreateDefTexture(&DefaultTexture);
ClearTransform(&DefaultTransform);
}
/*****************************************************************
*
* Miscellanous subroutines
*
*****************************************************************/
/*
* ----------
* *-- NOTE --*
* ----------
*
* These routines may have to be changed if your system uses a
* non-ascii standard. Sorry about that, but I guess most systems
* ARE ascii today...
*
*/
int ischar(int a)
{
int b;
b=-1;
if((a>=33)&&(a<=126)) b=0; /* chr(a) = "!..~" (all chars) */
return(b);
}
int isletter(int *a)
{
int b;
b=-1;
if((*a>=(int)'a')&&(*a<=(int)'z')) *a=*a-(int)'a'+(int)'A'; /* Make uppercase */
if(((*a>=(int)'A')&&(*a<=(int)'Z'))||(*a==(int)':')) b=0; /* chr(a) = "A..Z" or ":" */
return(b);
}
int isnumber(int a)
{
int b;
b=-1;
if(((a>=(int)'0')&&(a<=(int)'9'))||(a==(int)'-')||(a==(int)'.')) b=0; /* chr(a) = "0..9" or "-" or "." */
return(b);
}
int iscomment(int a)
{
int b;
b=-1;
if((a==(int)'#')||(a==(int)';')||(a==(int)'*')) b=0;
return(b);
}
int isnewline(int a)
{
int b;
b=-1;
if((a==(int)10)||(a==(int)13)) b=0;
return(b);
}
int getnextkeyword(FILE *f, char *keyword)
{
int itmp,i;
i=0;
keyword[0]=(char) 0;
itmp=fgetc(f);
while((itmp!=EOF)&&(isletter(&itmp)!=0)) {
if(iscomment(itmp)==0) {
while((itmp!=EOF)&&(isnewline(itmp)!=0)) {
itmp=fgetc(f);
}
}
itmp=fgetc(f);
}
while((itmp!=EOF)&&(isletter(&itmp)==0)&(i<99)) {
keyword[i]=(char)itmp;
itmp=fgetc(f);
i++;
}
if(itmp==EOF) { return(-1); }
else{
keyword[i]=(char)0;
return(0);
}
}
int getnextnumber(FILE *f, double *number)
{
int itmp,i;
char string[100];
i=0;
string[0]=(char)"0"; string[1]=(char)0;
itmp=fgetc(f);
while((itmp!=EOF)&&(isnumber(itmp)!=0)) {
if(iscomment(itmp)==0) {
while((itmp!=EOF)&&(isnewline(itmp)!=0)) {
itmp=fgetc(f);
}
}
itmp=fgetc(f);
}
while((itmp!=EOF)&&(isnumber(itmp)==0)&&(i<99)) {
string[i]=(char)itmp;
itmp=fgetc(f);
i++;
}
if(itmp==EOF) { return(-1); }
else{
string[i]=(char)0;
*number=atof(string);
return(0);
}
}
void set_ivalue(long *variable, long value, long min, long max, char *string)
{
if((value>=min)&&(value<=max)) *variable=value;
else {
fprintf(stderr,"\n Warning: Invalid value for %s: %ld\n",string,value);
if(value>max) *variable=max;
if(value<min) *variable=min;
fprintf(stderr," Set to: %ld\n",*variable);
}
}
void set_dvalue(double *variable, double value, double min, double max, char *string)
{
if((value>=min)&&(value<=max)) *variable=value;
else {
fprintf(stderr,"\n Warning: Invalid value for %s: %lf\n",string,value);
if(value>max) *variable=max;
if(value<min) *variable=min;
fprintf(stderr," Set to: %lf\n",*variable);
}
}